Skip to content

feat: expose stratum mining stats via Owner API#3897

Open
iho wants to merge 3 commits into
mimblewimble:stagingfrom
iho:feat/mining-status-api
Open

feat: expose stratum mining stats via Owner API#3897
iho wants to merge 3 commits into
mimblewimble:stagingfrom
iho:feat/mining-status-api

Conversation

@iho

@iho iho commented Jul 9, 2026

Copy link
Copy Markdown

Summary

Adds an Owner API endpoint for stratum mining statistics so operators running headless (no TUI) can inspect connected workers and share stats — the same data shown on the TUI mining tab.

Closes #3201

Changes

  • New get_mining_status method on Owner JSON-RPC (/v2/owner)
  • New types: MiningStatus / WorkerInfo in the API crate
  • Server wires live StratumStats into the Owner API via a provider callback
  • CLI: grin client miningstatus
  • Brief docs in doc/api/api.md

Example

{
  "jsonrpc": "2.0",
  "method": "get_mining_status",
  "params": [],
  "id": 1
}

Returns whether stratum is enabled/running, worker count, block height, network difficulty/hashrate, blocks found, and per-worker share stats for currently connected workers. When stratum is disabled, a provider still returns is_enabled: false. If no mining stats provider is wired into the Owner API, get_mining_status returns an internal error instead of masking the misconfiguration as disabled.

Test plan

  • Unit tests: MiningStatus serde roundtrip
  • Unit tests: Owner::get_mining_status without provider (error) and with provider via generated OwnerRpc JSON-RPC handler (wire response)
  • Unit tests: StratumStatsMiningStatus conversion (filters disconnected workers)
  • cargo check -p grin --bin grin
  • Manually: enable stratum, connect a miner, run grin client miningstatus

@wiesche89 wiesche89 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice and useful feature, and the endpoint is wired to the live StratumStats correctly. Before merging, I’d clarify whether the API should return only active workers, avoid masking a missing provider as disabled, and preserve the public node_apis signature.

Comment thread servers/src/common/stats.rs Outdated
Comment thread api/src/owner.rs Outdated
Comment thread api/src/handlers.rs
Comment thread api/src/types.rs
/// Whether the stratum server is enabled in config
pub is_enabled: bool,
/// Whether the stratum server is currently running
pub is_running: bool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source flag is set on startup but never cleared on listener failure or shutdown. Is “currently running” too strong for the API contract?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A port conflict still leaves this as true after the listener exits. Could we set it after a successful bind, clear it on exit, and test the bind-failure case?

Comment thread api/src/owner.rs
Add get_mining_status to the Owner JSON-RPC API so headless operators
can query the same stratum/worker stats shown on the TUI mining tab.
Wire live StratumStats into node_apis and add `grin client miningstatus`.

Closes mimblewimble#3201
@iho
iho force-pushed the feat/mining-status-api branch 2 times, most recently from f406b85 to 60178eb Compare July 17, 2026 00:56
- Filter mining status worker_stats to currently connected workers
  (StratumStats retains disconnected workers for the node lifetime),
  and drop the now always-true is_connected field from WorkerInfo
- Return an internal error from get_mining_status when no stats
  provider is wired, instead of masking it as disabled
- Restore the public node_apis signature; add
  node_apis_with_mining_stats for provider wiring
- Document is_running as set-once at startup
- Trim get_mining_status doc comment to match neighboring methods
@iho
iho force-pushed the feat/mining-status-api branch from 60178eb to 120e0cd Compare July 17, 2026 00:58
@iho
iho requested a review from wiesche89 July 17, 2026 01:01
blocks_found: stats.blocks_found,
network_hashrate: stats.network_hashrate,
minimum_share_difficulty: stats.minimum_share_difficulty,
// worker_stats retains every worker that ever connected; only expose

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The response is bounded now, but each request still scans the full worker history under the stats lock. Could we keep a bounded active-worker view and derive num_workers from it too?

Comment thread api/src/types.rs
/// Whether the stratum server is enabled in config
pub is_enabled: bool,
/// Whether the stratum server is currently running
pub is_running: bool,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A port conflict still leaves this as true after the listener exits. Could we set it after a successful bind, clear it on exit, and test the bind-failure case?

Comment thread api/src/types.rs Outdated
pub worker_stats: Vec<WorkerInfo>,
}

impl Default for MiningStatus {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has no caller besides its own test and duplicates StratumStats::default(). Could we remove the impl and test to avoid default drift?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the Default impl and its unit test so we do not duplicate / drift from StratumStats::default.

Comment thread api/src/owner.rs Outdated
}

#[test]
fn get_mining_status_with_provider() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we test this once through the generated JSON RPC handler? The current tests only call Owner directly, so the wire response is not covered.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — get_mining_status is now covered through the generated OwnerRpc JSON-RPC handler (success wire payload + missing-provider error path).

Comment thread api/src/owner.rs
pub fn get_mining_status(&self) -> Result<MiningStatus, Error> {
match &self.mining_stats {
Some(provider) => Ok(provider()),
None => Err(Error::Internal(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fixed now. Could you also update the PR description? It still says a missing provider returns a disabled default.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description updated: missing provider returns an internal error; disabled stratum still returns is_enabled: false via the wired provider.

@wiesche89

Copy link
Copy Markdown
Contributor

I’ve written a prototype Grin miner in Rust https://github.com/wiesche89/rust-miner . It can be used to test the new Owner API method end to end.
With a synced testnet node running, Stratum enabled on port 13416, and the Owner API listening on 13413, start a lightweight worker with:

./target/release/grin-cuckatoo-miner mine \
  --backend cpu \
  --edge-bits 25 \
  --node-port 13416 \
  --login api-test-1

I tested four connected miners this way. The API reported num_workers: 4 with four worker entries, then returned num_workers: 0 and an empty worker list after disconnecting them. C25 is only intended as a lightweight connection test, valid testnet mining requires C32.

Remove the unused MiningStatus Default impl (and its test) to avoid
drift from StratumStats::default. Cover get_mining_status through the
generated OwnerRpc JSON-RPC handler so the wire response is tested.
@iho
iho requested a review from wiesche89 July 25, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants